package main

import (
	"fmt"
	"log"
	"math/rand"
	"sync"
	"time"

	sentinel "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/base"
	"github.com/alibaba/sentinel-golang/core/flow"
)

const resName = "example-flow-qps-resource"

func main() {
	// 初始化一个sentinel
	err := sentinel.InitDefault()
	if err != nil {
		log.Fatalf("初始化sentinel出错: %v \n", err)
	}

	var globalTotal int
	var passTotal int
	var blockTotal int

	// 配置限流规则
	_, err = flow.LoadRules([]*flow.Rule{
		{
			Resource:               resName,
			TokenCalculateStrategy: flow.WarmUp, // 预热(冷启动)策略
			ControlBehavior:        flow.Reject,
			Threshold:              100,
			WarmUpPeriodSec:        30,
		},
	})
	if err != nil {
		log.Fatalf("加载限流规则失败: %+v \n", err)
		return
	}

	wg := sync.WaitGroup{}
	wg.Add(3)
	for i := 0; i < 3; i++ {
		go func() {
			for {
				globalTotal++
				e, block := sentinel.Entry(resName, sentinel.WithTrafficType(base.Inbound))
				if block != nil {
					blockTotal++
				} else {
					passTotal++
					e.Exit()
				}

				time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond)
			}
			wg.Done()
		}()
	}

	go func() {
		oldGlobalTotal := 0
		oldPassTotal := 0
		oldBlockTotal := 0
		for {
			oneGlobalTotal := globalTotal - oldGlobalTotal
			oldGlobalTotal = globalTotal
			onePassTotal := passTotal - oldPassTotal
			oldPassTotal = passTotal
			oneBlockTotal := blockTotal - oldBlockTotal
			oldBlockTotal = oldBlockTotal
			time.Sleep(time.Second)
			fmt.Println("oneGlobalTotal: ", oneGlobalTotal)
			fmt.Println("onePassTotal: ", onePassTotal)
			fmt.Println("oneBlockTotal: ", oneBlockTotal)
			fmt.Println("============================")
		}
	}()

	wg.Wait()
}
